package com.gitee.wsl.compose.ui.base

import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.DisposableEffectResult
import androidx.compose.runtime.DisposableEffectScope
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.withFrameMillis
import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
import androidx.compose.ui.modifier.ModifierLocal
import androidx.compose.ui.modifier.ModifierLocalMap
import androidx.compose.ui.modifier.ModifierLocalProvider
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.lifecycle.compose.LocalLifecycleOwner
import com.gitee.wsl.api.Closeable
import com.gitee.wsl.common.ui.ext.withFrameMillis
import com.gitee.wsl.compose.base.Local
import com.gitee.wsl.ext.K
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive

object View

@Composable
fun View.coroutineScope() = rememberCoroutineScope()

@Composable
fun View.softwareKeyboardController() = LocalSoftwareKeyboardController.current

@Composable
fun View.clipboardManager() = LocalClipboard.current

/**
 * 滚动状态,获取到滚动手势的偏移量，进一步定义滚动行为,必须返回消费的滚动距离量
 */
@Composable
fun View.scrollableState(consumeScrollDelta: (Float) -> Float) = rememberScrollableState(consumeScrollDelta)

inline val View.WindowInfo
    @Composable
    get() = LocalWindowInfo.current

inline val View.focusManager
    @Composable
    get() = LocalFocusManager.current

inline val View.lifecycleOwner
   @Composable
    get() = LocalLifecycleOwner.current

inline val View.density
    @Composable
    get() = LocalDensity.current

inline val View.contentColor
    @Composable
    get() = LocalContentColor.current

/**
 * 拖拽状态,
 */
@Composable
fun View.draggableState(onDelta: (Float) -> Unit) = rememberDraggableState(onDelta)

/**
 * 用于处理与交互状态相关的变化，比如元素的按下、点击或聚焦等。
 */
@Composable
fun View.interaction() = remember { MutableInteractionSource() }

//分发给父容器
@Composable
fun View.dispatch() = remember { NestedScrollDispatcher() }

@Suppress("ComposableNaming")
@Composable
fun View.onLaunch(key:Any?, block: suspend CoroutineScope.() -> Unit) = LaunchedEffect(key,block)

@Suppress("ComposableNaming")
@Composable
fun View.onLaunch(key1: Any?, key2: Any?, block: suspend CoroutineScope.() -> Unit) = LaunchedEffect(key1,key2,block)

@Suppress("ComposableNaming")
@Composable
fun View.onLaunch(key1: Any?, key2: Any?, key3: Any?, block: suspend CoroutineScope.() -> Unit) = LaunchedEffect(key1,key2,key3,block)

@Suppress("ComposableNaming")
@Composable
fun View.onLaunch(vararg keys: Any?, block: suspend CoroutineScope.() -> Unit) = LaunchedEffect(keys = keys,block)


@Suppress("ComposableNaming")
@Composable
fun View.onDisableLaunch(key:Any?, block: DisposableEffectScope.() -> DisposableEffectResult) = DisposableEffect(key,block)

@Suppress("ComposableNaming")
@Composable
fun View.onDisableLaunch(key1: Any?, key2: Any?, block: DisposableEffectScope.() -> DisposableEffectResult) = DisposableEffect(key1,key2,block)

@Suppress("ComposableNaming")
@Composable
fun View.onDisableLaunch(key1: Any?, key2: Any?, key3: Any?, block: DisposableEffectScope.() -> DisposableEffectResult) = DisposableEffect(key1,key2,key3,block)

@Suppress("ComposableNaming")
@Composable
fun View.onDisableLaunch(vararg keys: Any?, block: DisposableEffectScope.() -> DisposableEffectResult) = DisposableEffect(keys = keys,block)

@Suppress("ComposableNaming")
@Composable
fun View.onRefresh(block: () -> Unit) = SideEffect(block)

@Suppress("ComposableNaming")
@Composable
fun View.gameRun(block: Closeable.(before:Long,current:Long) -> Unit){
    LaunchedEffect(Unit) {
        var runAble = true
        val closeable = Closeable {
                runAble = false
                return@Closeable
        }
        while (runAble && isActive) {
                var previousTimeNanos = withFrameMillis { it }
                withFrameMillis {
                    closeable.block(previousTimeNanos, it)
                    previousTimeNanos = it
                }
        }
    }
}

fun View.modifierLocalMapOf( ) = androidx.compose.ui.modifier.modifierLocalMapOf()

/** Creates a [ModifierLocalMap] with a single key and value initialized to null. */
fun <T> View.modifierLocalMapOf(key: ModifierLocal<T>)= androidx.compose.ui.modifier.modifierLocalMapOf(key)

fun <T> View.modifierLocalMapOf(entry: Pair<ModifierLocal<T>, T>)= androidx.compose.ui.modifier.modifierLocalMapOf(entry)

fun View.modifierLocalMapOf(
    key1: ModifierLocal<*>,
    key2: ModifierLocal<*>,
    vararg keys: ModifierLocal<*>
)= androidx.compose.ui.modifier.modifierLocalMapOf(key1 = key1, key2 = key2, keys = keys)

fun View.modifierLocalMapOf(
    entry1: Pair<ModifierLocal<*>, Any>,
    entry2: Pair<ModifierLocal<*>, Any>,
    vararg entries: Pair<ModifierLocal<*>, Any>
) =  androidx.compose.ui.modifier.modifierLocalMapOf(entry1 = entry1, entry2 = entry2, entries = entries)

fun <T> View.modifierLocalOf(defaultFactory: () -> T) = androidx.compose.ui.modifier.modifierLocalOf(defaultFactory)

